package com.vincent.template.service.logic.impl;

import com.google.common.collect.Lists;
import com.vincent.template.commons.exception.Vct520Exception;
import com.vincent.template.domain.SysRolePo;
import com.vincent.template.dto.sys.role.RoleDto;
import com.vincent.template.repository.SysBindAuthGroupRoleRepository;
import com.vincent.template.repository.SysBindRoleAuthRepository;
import com.vincent.template.repository.SysBindUserGroupRoleRepository;
import com.vincent.template.repository.SysBindUserRoleRepository;
import com.vincent.template.repository.SysRoleRepository;
import com.vincent.template.service.logic.RoleService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Vincent Wang
 * @date 2021/3/25 16:19
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private SysRoleRepository roleRepository;
    @Autowired
    private SysBindUserRoleRepository bindUserRoleRepository;
    @Autowired
    private SysBindUserGroupRoleRepository bindUserGroupRoleRepository;
    @Autowired
    private SysBindRoleAuthRepository bindRoleAuthRepository;
    @Autowired
    private SysBindAuthGroupRoleRepository bindAuthGroupRoleRepository;

    @Override
    public List<RoleDto> findRoles() {
        List<SysRolePo> roles = roleRepository.findAll();
        if (CollectionUtils.isEmpty(roles)) {
            return Lists.newArrayList();
        }
        return roles.stream().map(role -> {
            RoleDto roleDto = new RoleDto();
            BeanUtils.copyProperties(role, roleDto);
            return roleDto;
        }).collect(Collectors.toList());
    }

    @Override
    public RoleDto findRoleById(Long id) {
        SysRolePo role = roleRepository.findById(id).orElse(null);
        if (role == null) {
            return null;
        }
        RoleDto roleDto = new RoleDto();
        BeanUtils.copyProperties(role, roleDto);
        return roleDto;
    }

    @Override
    public Long addRole(RoleDto roleDto) {
        SysRolePo role = roleRepository.findByCode(roleDto.getCode());
        Vct520Exception.throwIfTrue(role != null, "角色Code已存在：" + roleDto.getCode());
        role = new SysRolePo();
        BeanUtils.copyProperties(roleDto, role);
        return roleRepository.save(role).getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRole(Long id, RoleDto roleDto) {
        SysRolePo role = roleRepository.findById(id).orElse(null);
        Vct520Exception.throwIfEmpty(role, "角色不存在");
        if (!role.getCode().equals(roleDto.getCode())) {
            Vct520Exception.throwIfTrue(roleRepository.findByCode(roleDto.getCode()) != null,
                    "角色Code已存在：" + roleDto.getCode());
        }
        BeanUtils.copyProperties(roleDto, role, "id");
        roleRepository.save(role);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRole(Long id) {
        SysRolePo role = roleRepository.findById(id).orElse(null);
        Vct520Exception.throwIfEmpty(role, "角色不存在");
        Vct520Exception.throwIfTrue(CollectionUtils.isNotEmpty(bindUserRoleRepository.findByRoleId(id)),
                "有用户绑定了该角色，请先确认并解绑");
        Vct520Exception.throwIfTrue(CollectionUtils.isNotEmpty(bindUserGroupRoleRepository.findByRoleId(id)),
                "有用户组绑定了该角色，请先确认并解绑");
        roleRepository.delete(role);
        bindRoleAuthRepository.deleteByRoleId(id);
        bindAuthGroupRoleRepository.deleteByRoleId(id);
        return true;
    }
}
